﻿Imports System
Imports System.Collections
Imports System.Collections.Generic
Imports System.Diagnostics
Imports System.Runtime.CompilerServices
Imports System.Runtime.InteropServices
Imports System.Threading
Imports System.Workflow.Interop

Namespace System.Workflow.ComponentModel.Compiler
    Friend Class MetaDataReader
        ' Methods
        Friend Shared Function GetTypeRefNames(ByVal assemblyLocation As String) As IEnumerable
            Return New <GetTypeRefNames>d__0(-2) { _
                .<>3__assemblyLocation = assemblyLocation _
            }
        End Function

        Private Shared Function TokenTypeFromToken(ByVal token As UInt32) As MetadataTokenType
            Return (DirectCast(token, MetadataTokenType) And DirectCast(-16777216, MetadataTokenType))
        End Function


        ' Nested Types
        <CompilerGenerated> _
        Private NotInheritable Class <GetTypeRefNames>d__0
            Implements IEnumerable(Of Object), IEnumerable, IEnumerator(Of Object), IEnumerator, IDisposable
            ' Methods
            <DebuggerHidden> _
            Public Sub New(ByVal <>1__state As Integer)
                Me.<>1__state = <>1__state
                Me.<>l__initialThreadId = Thread.CurrentThread.ManagedThreadId
            End Sub

            Private Sub <>m__Finally17()
                Me.<>1__state = -1
                Me.<metaDataImport>5__4.CloseEnum(Me.<enumHandle>5__5)
            End Sub

            Private Sub <>m__Finally18()
                Me.<>1__state = 1
                If ((Me.<assemblyName>5__11 <> IntPtr.Zero) AndAlso (Me.<assemblyNameSize>5__12 > 0)) Then
                    Marshal.FreeCoTaskMem(Me.<assemblyName>5__11)
                    Me.<assemblyName>5__11 = IntPtr.Zero
                End If
                If ((Me.<assemblyMetadata>5__e.locale <> IntPtr.Zero) AndAlso (Me.<assemblyMetadata>5__e.localeSize > 0)) Then
                    Marshal.FreeCoTaskMem(Me.<assemblyMetadata>5__e.locale)
                    Me.<assemblyMetadata>5__e.locale = IntPtr.Zero
                End If
            End Sub

            Private Function MoveNext() As Boolean Implements IEnumerator.MoveNext
                Try 
                    Select Case Me.<>1__state
                        Case 0
                            Me.<>1__state = -1
                            Me.<metaDataDispenser>5__1 = TryCast(New MetaDataDispenser,IMetaDataDispenser)
                            If (Me.<metaDataDispenser>5__1 Is Nothing) Then
                                Throw New InvalidOperationException(String.Format(SR.GetString("Error_MetaDataInterfaceMissing"), Me.assemblyLocation, "IMetaDataDispenser"))
                            End If
                            Me.<guidMetaDataImport>5__2 = New Guid("7DAC8207-D3AE-4c75-9B67-92801A497D44")
                            Me.<metaDataImportObj>5__3 = Nothing
                            NativeMethods.ThrowOnFailure(Me.<metaDataDispenser>5__1.OpenScope(Me.assemblyLocation, 0, (Me.<guidMetaDataImport>5__2), Me.<metaDataImportObj>5__3))
                            Me.<metaDataImport>5__4 = TryCast(Me.<metaDataImportObj>5__3,IMetaDataImport)
                            If (Me.<metaDataImport>5__4 Is Nothing) Then
                                Throw New InvalidOperationException(String.Format(SR.GetString("Error_MetaDataInterfaceMissing"), Me.assemblyLocation, "IMetaDataImport"))
                            End If
                            Me.<enumHandle>5__5 = New IntPtr
                            Me.<typeRefs>5__6 = New UInt32(20  - 1) {}
                            Me.<typeRefCount>5__7 = 0
                            Me.<>1__state = 1
                            Do
                                NativeMethods.ThrowOnFailure(Me.<metaDataImport>5__4.EnumTypeRefs((Me.<enumHandle>5__5), Me.<typeRefs>5__6, DirectCast(Me.<typeRefs>5__6.Length, UInt32), (Me.<typeRefCount>5__7)))
                                Me.<typeRefIndex>5__8 = 0
                                Do While (Me.<typeRefIndex>5__8 < Me.<typeRefCount>5__7)
                                    Me.<typeRefNamePtr>5__9 = IntPtr.Zero
                                    NativeMethods.ThrowOnFailure(Me.<metaDataImport>5__4.GetTypeRefProps(Me.<typeRefs>5__6(Me.<typeRefIndex>5__8), Me.<resolutionScopeToken>5__b, Me.<typeRefNamePtr>5__9, 0, Me.<typeRefNameLength>5__a))
                                    If (Me.<typeRefNameLength>5__a <= 0) Then
                                        goto Label_0494
                                    End If
                                    Me.<typeRefName>5__c = String.Empty
                                    Me.<typeRefNamePtr>5__9 = Marshal.AllocCoTaskMem(CInt((2 * (Me.<typeRefNameLength>5__a + 1))))
                                    Try 
                                        NativeMethods.ThrowOnFailure(Me.<metaDataImport>5__4.GetTypeRefProps(Me.<typeRefs>5__6(Me.<typeRefIndex>5__8), Me.<resolutionScopeToken>5__b, Me.<typeRefNamePtr>5__9, Me.<typeRefNameLength>5__a, Me.<typeRefNameLength>5__a))
                                    Finally
                                        Me.<typeRefName>5__c = Marshal.PtrToStringUni(Me.<typeRefNamePtr>5__9)
                                        Marshal.FreeCoTaskMem(Me.<typeRefNamePtr>5__9)
                                    End Try
                                    Me.<metaDataAssemblyImport>5__d = [TryCast](Me.<metaDataImportObj>5__3,IMetaDataAssemblyImport)
                                    If (Me.<metaDataAssemblyImport>5__d Is Nothing) Then
                                        Throw New InvalidOperationException(String.Format(SR.GetString("Error_MetaDataInterfaceMissing"), Me.assemblyLocation, "IMetaDataAssemblyImport"))
                                    End If
                                    If (MetaDataReader.TokenTypeFromToken(Me.<resolutionScopeToken>5__b) <> MetadataTokenType.AssemblyRef) Then
                                        goto Label_0494
                                    End If
                                    Me.<publicKeyOrToken>5__f = IntPtr.Zero
                                    Me.<assemblyName>5__11 = IntPtr.Zero
                                    Me.<hashValueBlob>5__13 = IntPtr.Zero
                                    NativeMethods.ThrowOnFailure(Me.<metaDataAssemblyImport>5__d.GetAssemblyRefProps(Me.<resolutionScopeToken>5__b, Me.<publicKeyOrToken>5__f, Me.<publicKeyOrTokenSize>5__10, Me.<assemblyName>5__11, 0, Me.<assemblyNameSize>5__12, Me.<assemblyMetadata>5__e, Me.<hashValueBlob>5__13, Me.<hashValueSize>5__14, Me.<assemblyRefFlags>5__15))
                                    If (Me.<assemblyNameSize>5__12 > 0) Then
                                        Me.<assemblyName>5__11 = Marshal.AllocCoTaskMem(CInt((2 * (Me.<assemblyNameSize>5__12 + 1))))
                                    End If
                                    If (Me.<assemblyMetadata>5__e.localeSize > 0) Then
                                        Me.<assemblyMetadata>5__e.locale = Marshal.AllocCoTaskMem(CInt((2 * (Me.<assemblyMetadata>5__e.localeSize + 1))))
                                    End If
                                    Me.<>1__state = 3
                                    If ((Me.<assemblyNameSize>5__12 > 0) OrElse (Me.<assemblyMetadata>5__e.localeSize > 0)) Then
                                        NativeMethods.ThrowOnFailure(Me.<metaDataAssemblyImport>5__d.GetAssemblyRefProps(Me.<resolutionScopeToken>5__b, Me.<publicKeyOrToken>5__f, Me.<publicKeyOrTokenSize>5__10, Me.<assemblyName>5__11, Me.<assemblyNameSize>5__12, Me.<assemblyNameSize>5__12, Me.<assemblyMetadata>5__e, Me.<hashValueBlob>5__13, Me.<hashValueSize>5__14, Me.<assemblyRefFlags>5__15))
                                    End If
                                    Me.<publicKeyString>5__16 = String.Empty
                                    Dim i As Integer
                                    For i = 0 To Me.<publicKeyOrTokenSize>5__10 - 1
                                        Me.<publicKeyString>5__16 = (Me.<publicKeyString>5__16 & String.Format("{0}", Marshal.ReadByte(Me.<publicKeyOrToken>5__f, i).ToString("x2")))
                                    Next i
                                    Me.<>2__current = String.Format("{0}, {1}, Version={2}.{3}.{4}.{5}, Culture={6}, PublicKeyToken={7}", New Object() { Me.<typeRefName>5__c, Marshal.PtrToStringUni(Me.<assemblyName>5__11), Me.<assemblyMetadata>5__e.majorVersion, Me.<assemblyMetadata>5__e.minorVersion, Me.<assemblyMetadata>5__e.buildNumber, Me.<assemblyMetadata>5__e.revisionNumber, If(String.IsNullOrEmpty(Marshal.PtrToStringUni(Me.<assemblyMetadata>5__e.locale)), "neutral", Marshal.PtrToStringUni(Me.<assemblyMetadata>5__e.locale)), If(String.IsNullOrEmpty(Me.<publicKeyString>5__16), "null", Me.<publicKeyString>5__16) })
                                    Me.<>1__state = 4
                                    Return True
                                Label_0487:
                                    Me.<>1__state = 3
                                    Me.<>m__Finally18
                                Label_0494:
                                    Me.<typeRefIndex>5__8 += 1
                                Loop
                            Loop While (Me.<typeRefCount>5__7 > 0)
                            Me.<>m__Finally17
                            Exit Select
                        Case 4
                            goto Label_0487
                    End Select
                    Return False
                Fault
                    Me.System.IDisposable.Dispose
                End Try
            End Function

            <DebuggerHidden> _
            Private Function System.Collections.Generic.IEnumerable<System.Object>.GetEnumerator() As IEnumerator([Of] Object) Implements IEnumerable([Of] Object).GetEnumerator
                Dim d__ As <GetTypeRefNames>d__0
                If ((Thread.CurrentThread.ManagedThreadId = Me.<>l__initialThreadId) AndAlso (Me.<>1__state = -2)) Then
                    Me.<>1__state = 0
                    d__ = Me
                Else
                    d__ = New <GetTypeRefNames>d__0(0)
                End If
                d__.assemblyLocation = Me.<>3__assemblyLocation
                Return d__
            End Function

            <DebuggerHidden> _
            Private Function System.Collections.IEnumerable.GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
                Return Me.System.Collections.Generic.IEnumerable<System.Object>.GetEnumerator
            End Function

            <DebuggerHidden> _
            Private Sub System.Collections.IEnumerator.Reset() Implements IEnumerator.Reset
                Throw New NotSupportedException
            End Sub

            Private Sub System.IDisposable.Dispose() Implements IDisposable.Dispose
                Select Case Me.<>1__state
                    Case 1, 3, 4
                        Try 
                            Select Case Me.<>1__state
                                Case 3, 4
                                    Try 
                                    Finally
                                        Me.<>m__Finally18
                                    End Try
                                    Exit Select
                            End Select
                        Finally
                            Me.<>m__Finally17
                        End Try
                        Exit Select
                    Case 2
                        Exit Select
                    Case Else
                        Return
                End Select
            End Sub


            ' Properties
            Private ReadOnly Property System.Collections.Generic.IEnumerator<System.Object>.Current As Object
                <DebuggerHidden> _
                Get
                    Return Me.<>2__current
                End Get
            End Property

            Private ReadOnly Property System.Collections.IEnumerator.Current As Object
                <DebuggerHidden> _
                Get
                    Return Me.<>2__current
                End Get
            End Property


            ' Fields
            Private <>1__state As Integer
            Private <>2__current As Object
            Public <>3__assemblyLocation As String
            Private <>l__initialThreadId As Integer
            Public <assemblyMetadata>5__e As AssemblyMetadata
            Public <assemblyName>5__11 As IntPtr
            Public <assemblyNameSize>5__12 As UInt32
            Public <assemblyRefFlags>5__15 As UInt32
            Public <enumHandle>5__5 As IntPtr
            Public <guidMetaDataImport>5__2 As Guid
            Public <hashValueBlob>5__13 As IntPtr
            Public <hashValueSize>5__14 As UInt32
            Public <metaDataAssemblyImport>5__d As IMetaDataAssemblyImport
            Public <metaDataDispenser>5__1 As IMetaDataDispenser
            Public <metaDataImport>5__4 As IMetaDataImport
            Public <metaDataImportObj>5__3 As Object
            Public <publicKeyOrToken>5__f As IntPtr
            Public <publicKeyOrTokenSize>5__10 As UInt32
            Public <publicKeyString>5__16 As String
            Public <resolutionScopeToken>5__b As UInt32
            Public <typeRefCount>5__7 As UInt32
            Public <typeRefIndex>5__8 As Integer
            Public <typeRefName>5__c As String
            Public <typeRefNameLength>5__a As UInt32
            Public <typeRefNamePtr>5__9 As IntPtr
            Public <typeRefs>5__6 As UInt32()
            Public assemblyLocation As String
        End Class

        <StructLayout(LayoutKind.Sequential)> _
        Private Structure AssemblyMetadata
            Public majorVersion As UInt16
            Public minorVersion As UInt16
            Public buildNumber As UInt16
            Public revisionNumber As UInt16
            Public locale As IntPtr
            Public localeSize As UInt32
            Public processorIds As IntPtr
            Public processorIdCount As UInt32
            Public osInfo As IntPtr
            Public osInfoCount As UInt32
        End Structure

        Private Class Guids
            ' Fields
            Public Const CLSID_MetaDataDispenser As String = "E5CB7A31-7512-11d2-89CE-0080C792E5D8"
            Public Const IID_IMetaDataAssemblyImport As String = "EE62470B-E94B-424e-9B7C-2F00C9249F93"
            Public Const IID_IMetaDataDispenser As String = "809C652E-7396-11d2-9771-00A0C9B4D50C"
            Public Const IID_IMetaDataImport As String = "7DAC8207-D3AE-4c75-9B67-92801A497D44"
        End Class

        <ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("EE62470B-E94B-424e-9B7C-2F00C9249F93")> _
        Private Interface IMetaDataAssemblyImport
            Sub GetAssemblyProps()
            Function GetAssemblyRefProps(<[In]> ByVal assemblyRefToken As UInt32, <Out> ByRef publicKeyOrToken As IntPtr, <Out> ByRef sizePublicKeyOrToken As UInt32, ByVal assemblyName As IntPtr, <[In]> ByVal assemblyNameBufferSize As UInt32, <Out> ByRef assemblyNameSize As UInt32, <Out> ByRef assemblyMetaData As AssemblyMetadata, <Out> ByRef hashValueBlob As IntPtr, <Out> ByRef hashValueSize As UInt32, <Out> ByRef assemblyRefFlags As UInt32) As Integer
        End Interface

        <ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("809C652E-7396-11d2-9771-00A0C9B4D50C")> _
        Private Interface IMetaDataDispenser
            Sub DefineScope()
            Function OpenScope(<[In], MarshalAs(UnmanagedType.LPWStr)> ByVal scopeName As String, ByVal openFlags As UInt32, <[In]> ByRef riid As Guid, <Out, MarshalAs(UnmanagedType.IUnknown)> ByRef unknown As Object) As Integer
            Sub OpenScopeOnMemory()
        End Interface

        <ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("7DAC8207-D3AE-4c75-9B67-92801A497D44")> _
        Private Interface IMetaDataImport
            Sub CloseEnum(<[In]> ByVal enumHandle As IntPtr)
            Sub CountEnum()
            Sub ResetEnum()
            Sub EnumTypeDefs()
            Sub EnumInterfaceImpls()
            Function EnumTypeRefs(<[In], Out> ByRef enumHandle As IntPtr, <[In], Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex:=2)> ByVal rTypeRefs As UInt32(), ByVal cMax As UInt32, ByRef typeRefs As UInt32) As Integer
            Sub FindTypeDefByName()
            Sub GetScopeProps()
            Sub GetModuleFromScope()
            Sub GetTypeDefProps()
            Sub GetInterfaceImplProps()
            Function GetTypeRefProps(<[In]> ByVal typeRefToken As UInt32, <Out> ByRef resolutionScopeToken As UInt32, ByVal typeRefName As IntPtr, ByVal nameLength As UInt32, <Out> ByRef actualLength As UInt32) As Integer
        End Interface

        <ComImport, Guid("E5CB7A31-7512-11d2-89CE-0080C792E5D8")> _
        Private Class MetaDataDispenser
            ' Methods
            <MethodImpl(MethodImplOptions.InternalCall, MethodCodeType:=MethodCodeType.Runtime)> _
            Public Sub New()

        End Class

        Private Enum MetadataTokenType
            ' Fields
            AssemblyRef = &H23000000
            ModuleRef = &H1A000000
        End Enum

        <StructLayout(LayoutKind.Sequential)> _
        Private Structure OsInfo
            Private osPlatformId As UInt32
            Private osMajorVersion As UInt32
            Private osMinorVersion As UInt32
        End Structure
    End Class
End Namespace

